# -*- encoding: utf-8 -*-
#
# Copyright (C) 2008 Håvard Gulldahl.
#
# Licensed under the GNU Public License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.gnu.org/licenses/gpl-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

__author__ = u'<havard@gulldahl.no> Håvard Gulldahl'
__license__ = 'GPL v2'

import logging
import atom, gdata, gdata.contacts

PHONE_CAR = 'http://schemas.google.com/g/2005#car' #  Number of a car phone.
PHONE_FAX = 'http://schemas.google.com/g/2005#fax' #
PHONE_GENERAL = 'http://schemas.google.com/g/2005#general' # or not specified  Unknown or unspecified type, such as a business phone number that doesn't belong to a particular person.
PHONE_HOME = 'http://schemas.google.com/g/2005#home' #
PHONE_HOME_FAX = 'http://schemas.google.com/g/2005#home_fax' #
PHONE_INTERNAL = 'http://schemas.google.com/g/2005#internal-extension' #  Phone number that makes sense only in a context known to the user (such as an enterprise PBX).
PHONE_MOBILE = 'http://schemas.google.com/g/2005#mobile' #
PHONE_OTHER = 'http://schemas.google.com/g/2005#other' #  A special type of number for which no other rel value makes sense. For example, a TTY device. label can be used to indicate the actual type.
PHONE_PAGER = 'http://schemas.google.com/g/2005#pager' #
PHONE_SATELLITE = 'http://schemas.google.com/g/2005#satellite' #
PHONE_VOIP = 'http://schemas.google.com/g/2005#voip' #
PHONE_WORK = 'http://schemas.google.com/g/2005#work' #
PHONE_WORK_FAX = 'http://schemas.google.com/g/2005#work_fax' #



class Organization(gdata.contacts.Organization):
  def ToVCard(self):
    r = ''
    if self.org_name:
      r += 'ORG'
      if self.primary == 'true': r+=';TYPE=PREF'
      r += ':%s\r\n' % self.org_name.text
    if self.org_title:
      r += 'TITLE:%s\r\n' % self.org_title.text
    return r

class PostalAddress(gdata.contacts.PostalAddress):
  def ToVCard(self):
    r = 'ADR'
    if self.primary == 'true': r+=';TYPE=PREF'
    r += ':%s\r\n' % self.text
    return r

class IM(gdata.contacts.IM):
  def ToVCard(self):
    try: # try to get protocol (this is a mess, but VCard doesn't know about IM)
      r = 'X-%s' % self.protocol.split('#')[1]
    except:
      return ''
    if self.primary == 'true': r+=';TYPE=PREF'
    r += ':%s\r\n' % self.address
    return r

class Email(gdata.contacts.Email):
  def ToVCard(self):
    r = 'EMAIL'
    if self.primary == 'true': r+=';TYPE=PREF'
    r += ':%s\r\n' % self.address
    return r

class PhoneNumber(gdata.contacts.PhoneNumber):
  def ToVCard(self):
    r = 'TEL'
    r += ':%s\r\n' % self.text
    return r

class ContactEntry(gdata.contacts.ContactEntry):
  """GContacts superclass of gdata.ContactEntry, providing VCard ++ support"""
  _children = gdata.contacts.ContactEntry._children.copy()

  # overriding with VCard-aware elements
  _children['{%s}postalAddress' % gdata.GDATA_NAMESPACE] = ('postal_address', [PostalAddress])
  _children['{%s}phoneNumber' % gdata.GDATA_NAMESPACE] = ('phone_number', [PhoneNumber])
  _children['{%s}organization' % gdata.GDATA_NAMESPACE] = ('organization', Organization)
  _children['{%s}email' % gdata.GDATA_NAMESPACE] = ('email', [Email])
  _children['{%s}im' % gdata.GDATA_NAMESPACE] = ('im', [IM])

  def ToVCard(self):
    "Return a utf-8 encoded VCARD string"
    card = 'BEGIN:VCARD\r\n'
    card +='FN:%s\r\n' % self.PrettyName()
    card +='N:%s\r\n' % self.PrettyName()
    if self.updated:
      card +='REV:%s\r\n' % self.updated.text
    #card +='SOURCE:%s\r\n' % self.GetSelfLink().href
    for res in ( self.phone_number,
                 self.postal_address,
                 self.im,
                 self.email,
                 ):
      if res:
        card += ''.join([elem.ToVCard() for elem in res])
    if self.organization:
      card += self.organization.ToVCard()
    if self.content:
      card += 'NOTE:%s\r\n' % self.content.text
    card += 'VERSION:3.0\r\nEND:VCARD\r\n\r\n'
    return card

  def PrettyName(self):
    if self.title is not None and self.title.text is not None:
      return self.title.text
    else:
      try:
        user, server = self.email[0].address.split('@')
        names = " ".join(user.split('.')).title()
        return names + ' (%s)' % '/'.join(server.split('.')[:-1])
      except Exception, e:
        logging.error('gcontactsbase.ContactEntry.PrettyName could not parse name: %s', e)
        return None
    return self.PrimaryEmailAddress()
    
  def PrettyEmail(self):
    try:
      return '"%s" <%s>' % (self.PrettyName(), self.email[0].address)
    except IndexError:
      return None

  def PrimaryEmailAddress(self):
    for e in self.email:
      if e is not None and e.address is not None:
        return e.address
    return None

def ContactEntryFromString(xml_string):
  return atom.CreateClassFromXMLString(ContactEntry, xml_string)

class ContactsFeed(gdata.contacts.ContactsFeed):
  """GContacts superclass of gdata.ContactsFeed, providing VCard aware classes"""
  _children = gdata.contacts.ContactsFeed._children.copy()
  _children['{%s}entry' % atom.ATOM_NAMESPACE] = ('entry', [ContactEntry])

def ContactsFeedFromString(xml_string):
  return atom.CreateClassFromXMLString(ContactsFeed, xml_string)
